/*	This file is part of AstroAttack.
*
*	AstroAttack is free software; you can redistribute it and/or modify
*	it under the terms of the GNU General Public License as published by
*	the Free Software Foundation; either version 2 of the License, or
*	(at your option) any later version.
*	
*	AstroAttack is distributed in the hope that it will be useful,
*	but WITHOUT ANY WARRANTY; without even the implied warranty of
*	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*	GNU General Public License for more details.
*	
*	You should have received a copy of the GNU General Public License
*	along with AstroAttack; if not, write to the Free Software
*	Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*	
*	$Id: ImageCache.java 29 2006-12-27 20:33:26Z xdracox $
*/

/**	The AstroAttack package contains all the classes that belong to the
*	AstroAttack program.
*/
package AstroAttack;

import java.awt.Image;
import java.awt.Toolkit;
import java.awt.MediaTracker;
import java.awt.Component;

import java.util.Map;
import java.util.TreeMap;

import java.net.URL;

import java.io.FileNotFoundException;

/**	The ImageCache class loads images and keeps them in a cache. It uses
*	a TreeMap to keep a relationship between the image and it's location.
*/
public class ImageCache
{
	/**	The single instance of the ImageCache class. */
	private static ImageCache m_ref = null;
	
	/**	Since the ImageCache class is a singleton, this method is used to
	*	retrieve or create the instance of it.
	*	@param	p_imgPath	path to where the image files are located
	*	@param	comp		the Component to use for the MediaTracker
	*	@return	
	*/
	public static ImageCache getCache(String p_imgPath, Component comp)
	{
		if ( m_ref == null )
			m_ref = new ImageCache(p_imgPath, comp);
		
		return m_ref;
	}
	
	/** This method returns the already initialized instance of the ImageCache
	*	or null if it has not been initialized.
	*	@return	the 
	*/
	public static ImageCache getCache()
	{
		return m_ref;
	}
	
	/** Map of all the loaded images. */
	private Map<String, Image> m_imgs;
	/** Location of all the image files. */
	private String m_imgPath;
	/**	MediaTracker that's used for loading images. */
	private MediaTracker m_tracker;
	/**	ID for the last image added. */
	private int m_id = 0;
	
	/**	Constructor initializes private members.
	*	@param	p_imgPath	path to where the image files are located
	*/
	private ImageCache(String p_imgPath, Component comp)
	{
		setImgPath(p_imgPath);
		m_imgs = new TreeMap<String, Image>();
		m_tracker = new MediaTracker(comp);
	}
	
	/**	Changed the location of the images.
	*	@param	p_imgPath	new location
	*/
	public void setImgPath(String p_imgPath)
	{
		Debug.println("Changing image path:");
		Debug.println("\told path: " + m_imgPath);
		
		if ( !p_imgPath.endsWith("/") )
			p_imgPath += "/";
		m_imgPath = p_imgPath;
		
		Debug.println("\tnew path: " + m_imgPath);
	}
	
	/** The loadAll() method adds all of the images that will be used to a map
	*	so that all classes can quickly access them later.
	*	@param	p_imgs	the files to load
	*   @return true if all images were loaded correctly
	*/
	public boolean loadAll(String[]p_imgs)
	{
		Debug.println("Loading images...");
		//add all images
		for(int i=0;i<p_imgs.length;i++)
		{
			String path = m_imgPath + p_imgs[i];
			
			Debug.print("\tloading: " + path + "... ");
			URL url = getClass().getClassLoader().getResource(path);
			
			if ( url != null )
			{
				Image img = Toolkit.getDefaultToolkit().createImage(url);
				m_imgs.put(p_imgs[i], img);
				m_tracker.addImage(img, m_id);
				Debug.println("ok");
			}
			else
				Debug.println("file not found");
		}
		
		//wait for all images to load, error, or abort
		try
		{
			m_tracker.waitForAll();
		}
		catch(Exception e)
		{
			Debug.println("MediaTracker thread Interrupted");
		}
		
		if(m_tracker.statusAll(false) == MediaTracker.COMPLETE)
			return true;
		
		Debug.println("Searching for failed image loads:");
		//find which images did not load correctly
		for(int i=0;i<p_imgs.length;i++)
		{
			if(m_tracker.statusID(i, false) != MediaTracker.COMPLETE)
			{
				if(m_tracker.statusID(i, false) == MediaTracker.ABORTED)
					Debug.println("\t" + p_imgs[i] + " aborted.");
				else
					Debug.println("\t" + p_imgs[i] + " errored.");
			}
		}
		return false;
	}
	
	
	/** The getImage() retrieves an image that was previously loaded by this
	*	ImageCache
	*	@param	p_img	the file to load
	*	@return	the loaded image
	*/
	public Image getImage(String p_imgName)
	{
		Debug.println("Getting image: " + p_imgName);
		
		if(m_imgs.get(p_imgName) == null)
			Debug.println("\t" + p_imgName + " was not loaded.");
		
		return m_imgs.get(p_imgName);
	}
}
